#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "scanner.h"
#include "string.h"
#include "dict.h"
#include "tag.h"


int
scan_tag(const char *__tagName, char **__offset, char **__start, size_t *__len, string_t *__dst, uint8_t sflags)
{
  char *found = NULL, *start = NULL, *end = NULL, *tag_start = NULL;
  size_t start_tag_len;
  int retval = -1;
  string_t *tag = create_empty_string();

  found = *(__offset);
  if ( (found = strstr( found, build_tag_str(__tagName, START_TAG, tag) )) )
  {
    tag_start = found;
    start_tag_len = get_strlen(tag);
    start = found + start_tag_len;
    if ( (found = strstr( start, build_tag_str(__tagName, END_TAG, tag) )) )
    {
      end = found;
      if (__len)
      {
        *(__len) = (end - tag_start);
      }
      if (__start)
      {
        *(__start) = tag_start;
      }
      if ( start == end ) {
        retval = SCANERR_NOVALID;
      } else if ( *start == '_' ) {
        if ( (start+1) == end ) {
          retval = SCANERR_NOVALID;
        } else {
          if (sflags & SCANFLG_TAGONLY) {
            if ( (found = strchr(start, ' ')) && found < end ) {
              retval = SCANERR_NOVALID;
            } else {
              set_nstring(__dst, start+1, end-start-1);
              retval = SCANERR_SIMPLETAG;
            }
          } else {
            set_string(__dst, "var=\"");
            if ( (found = strchr(start, ' ')) && found < end ) {
              add_nstring(__dst, start+1, found-start-1);
              add_string(__dst, "\"");
              add_nstring(__dst, found, end-found);
            } else {
              add_nstring(__dst, start+1, end-start-1);
              add_string(__dst, "\"");
            }
            retval = SCANERR_SIMPLETAG;
          }
        }
      } else if ( (found = strstr( start, build_tag_str(__tagName, START_ELEM, tag) )) && found < end )
        {
          retval = SCANERR_NOVALID;
        } else {
          start++;
          if (__dst)
          {
            set_nstring(__dst, start, end-start);
          }
          retval = SCANERR_OK;
        }
    } else {
      retval = SCANERR_NOVALID;
    }
  } else {
    retval = SCANERR_NOTFOUND;
  }

  *(__offset) = start;
  free_string((string_t *)tag);
  return (retval);
}

int
scan_tag_attr(char **_offset, dict_t *dst)
{
  int retval = -1;
  uint8_t jmp;
  char sep;
  char *end = NULL;
  char *start = *(_offset);
  string_t *key = create_empty_string();
  string_t *value = create_empty_string();

  if ( (end = (char *) strstr( start, "=" )) )
  {
    if ( *(end + 1) == '\0' )
    {
      start = end + 1;
      retval = SCANERR_NOVALID;
    } else {
      set_nstring(key, start, (end - start));
      start = (char *)(end + 1);
      sep = *( (char *)start );
      if (sep == '"')
      {
        start++;
        jmp = 2;
      } else if (sep == '\'')
        {
          start++;
          jmp = 2;
        } else {
          sep = ' ';
          jmp = 1;
        }
      end = strchr(start, sep);
      if (!end) end = (char *)(start + strlen(start));
      set_nstring(value, start, (end - start));
      if ( strlen(end) >= jmp )
      {
        start = end + jmp;
      } else {
        if (sep == '\'' || sep == '"') start = end + 1;
          else start = end;
      }
      if (dst) insert_str(dst, key, value);
      retval = SCANERR_OK;
    }
  } else {
    if ( strlen(start) != 0 )
    {
      start = (char *)(start + strlen(start));
      retval = SCANERR_NOVALID;
    } else {
      retval = SCANERR_NOTFOUND;
    }
  }

  *(_offset) = start;
  free_string(key);
  free_string(value);
  return (retval);
}

void
print_str_cutout(string_t *str, char *sptr, uint8_t max_cutout)
{
  char *begin = NULL;
  char *s = (char *)get_string(str);
  uint8_t len, i;
  int cpos;
  string_t *result = create_empty_string();

  begin = sptr;
  for ( i = 0; i < max_cutout; i++ )
  {
    if ( (char *)(begin-i) == s )
    {
      break;
    }
  }
  len = strnlen(sptr, max_cutout);
  set_nstring(result, (sptr - i), (i + len) );
  replace_string(result, "\n", "\\n", 2);
  replace_string(result, "\t", "\\t", 2);
  cpos = (int)( get_strlen(result) / 2 );
  fprintf(stderr, "  near: %s\n"
                  "        ", get_string(result));
  for ( i = 0; i < cpos; i++ ) fprintf(stderr, " ");
  fprintf(stderr, "^\n");
  free_string(result);
}

